# -*- coding: utf-8 -*-
# coding by liuyunfei 
# 2021-4-12


from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox
from PyQt5.QtCore import QThread, pyqtSignal, QDateTime, QObject, QMutexLocker, QMutex, QTimer
from PyQt5.QtGui import QPixmap
from PyQt5 import Qt, QtCore

import sys
import time
import cv2
import numpy as np
import socket
import os
import glob
import threading
import pyrealsense2 as rs

from demoui import Ui_MainWindow
from utils import *

# global variable define
is_using_usb_camera = True
is_using_realsense = False
is_using_file = False
is_using_rtsp = False
camera_id = 0
file_path = ""
rtsp_url = ""
d435_pipline = None
usb_cap = None

# 线程安全锁 定义
org_img_mutex = QMutex()

# 全局变量
current_org_img = None


class D435ImageThread(QObject):
    update_org_image = pyqtSignal(list)    
    def __init__(self, camera):
        super(D435ImageThread, self).__init__()
        self.camera = camera

    def run(self):
        while is_using_realsense:
            frames = self.camera.wait_for_frames()
            img = frames.get_color_frame()
            color_image = np.asanyarray(img.get_data())
            if img is not None:                
                self.update_org_image.emit([color_image])
            time.sleep(0.01)

class USBImageThread(QObject):
    update_org_image = pyqtSignal(list)    
    def __init__(self, camera):
        super(USBImageThread, self).__init__()
        self.camera = camera

    def run(self):
        while is_using_usb_camera:
            ret,frame = self.camera.read()
            print(ret)
            #img = frames.get_color_frame()
            #color_image = np.asanyarray(img.get_data())
            if frame is not None:             
                self.update_org_image.emit([frame])
            time.sleep(0.01)


class MyWindow(QMainWindow,Ui_MainWindow):
    def __init__(self, parent=None):
        super(MyWindow, self).__init__(parent)
        self.setupUi(self)

        self.source_option1.clicked.connect(self.btn_check_usb_camera)
        self.source_option2.clicked.connect(self.btn_check_d435)
        self.source_option3.clicked.connect(self.btn_check_file)
        self.source_option4.clicked.connect(self.btn_check_rtsp)
        self.source_set_btn.clicked.connect(self.btn_source_set)
        self.source_reset_btn.clicked.connect(self.btn_source_reset)

        self.camera_no.setText("0")
        self.source_reset_btn.setEnabled(False)
        

    def init_d435(self):
        global d435_pipline
        d435_pipline = rs.pipeline()
        config = rs.config()
        #config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30)
        config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)
        d435_pipline.start(config)

    def init_usb(self):
        global usb_cap
        global camera_id
        camerano = self.camera_no.text()
        if camerano == "":
            print("camera no is empty")
        else:
            camera_id = int(camerano)
            usb_cap = cv2.VideoCapture(camera_id)


    def btn_check_usb_camera(self):
        global is_using_usb_camera
        global is_using_realsense
        global is_using_file
        global is_using_rtsp
        if (self.source_option1.isChecked()):
            is_using_usb_camera = True
            is_using_realsense = False
            is_using_file = False
            is_using_rtsp = False
        else:
            is_using_usb_camera = False
            is_using_realsense = True
            is_using_file = True
            is_using_rtsp = True

    def btn_check_d435(self):
        global is_using_usb_camera
        global is_using_realsense
        global is_using_file
        global is_using_rtsp
        if (self.source_option2.isChecked()):
            is_using_usb_camera = False
            is_using_realsense = True
            is_using_file = False
            is_using_rtsp = False
        else:
            is_using_usb_camera = True
            is_using_realsense = False
            is_using_file = True
            is_using_rtsp = True
        
        self.init_d435()


    def btn_check_file(self):
        global is_using_usb_camera
        global is_using_realsense
        global is_using_file
        global is_using_rtsp
        if (self.source_option3.isChecked()):
            is_using_usb_camera = False
            is_using_realsense = False
            is_using_file = True
            is_using_rtsp = False
        else:
            is_using_usb_camera = True
            is_using_realsense = True
            is_using_file = False
            is_using_rtsp = True

    def btn_check_rtsp(self):
        global is_using_usb_camera
        global is_using_realsense
        global is_using_file
        global is_using_rtsp
        if (self.source_option4.isChecked()):
            is_using_usb_camera = False
            is_using_realsense = False
            is_using_file = False
            is_using_rtsp = True
        else:
            is_using_usb_camera = True
            is_using_realsense = True
            is_using_file = True
            is_using_rtsp = False
    
    def btn_source_set(self):
        global camera_id
        global file_path
        global rtsp_url
        global is_using_usb_camera
        global is_using_realsense
        global is_using_file
        global is_using_rtsp

        if (self.source_option1.isChecked()):
            is_using_usb_camera = True
        if (self.source_option2.isChecked()):
            is_using_realsense = True
        if (self.source_option3.isChecked()):
            is_using_file = True
        if (self.source_option4.isChecked()):
            is_using_rtsp = True

        self.init_usb()

        if self.camera_no.text() != "":
            camera_id = int(self.camera_no.text())
        file_path = self.file_path.text()
        rtsp_url = self.url_path.text()
        self.start_camera_or_video()

        self.source_reset_btn.setEnabled(True)
        self.source_option1.setEnabled(False)
        self.source_option2.setEnabled(False)
        self.source_option3.setEnabled(False)
        self.source_option4.setEnabled(False)
        self.source_set_btn.setEnabled(False)
    
    def btn_source_reset(self):
        global is_using_usb_camera
        global is_using_realsense
        global is_using_file
        global is_using_rtsp
        if is_using_realsense:
            is_using_realsense = False
        if is_using_usb_camera:
            is_using_usb_camera = False
        if is_using_file:
            is_using_file = False
        if is_using_rtsp:
            is_using_rtsp = False
        time.sleep(0.01)
        self.uithread1.quit()
        self.uithread1.wait()
        self.source_set_btn.setEnabled(True)
        self.source_option1.setEnabled(True)
        self.source_option2.setEnabled(True)
        self.source_option3.setEnabled(True)
        self.source_option4.setEnabled(True)
        self.source_reset_btn.setEnabled(False)



    def start_camera_or_video(self):
        if is_using_realsense:
            self.update_org_img = D435ImageThread(d435_pipline)
            self.update_org_img.update_org_image.connect(self.update_org_image)
            self.uithread1 = QThread()
            self.update_org_img.moveToThread(self.uithread1)
            self.uithread1.started.connect(self.update_org_img.run)
            #self.uithread1.setPriority(QThread.HighPriority)
            self.uithread1.start()

        if is_using_usb_camera:
            self.update_org_img = USBImageThread(usb_cap)
            self.update_org_img.update_org_image.connect(self.update_org_image)
            self.uithread1 = QThread()
            self.update_org_img.moveToThread(self.uithread1)
            self.uithread1.started.connect(self.update_org_img.run)
            #self.uithread1.setPriority(QThread.HighPriority)
            self.uithread1.start()
    

    def update_org_image(self, list_tmp):
        global current_org_img
        pix = cv2img_to_Qpixmap(list_tmp[0]) # QPixmap to show  在显示的时候才把格式转成QPixmap
        org_img_mutex.lock()
        current_org_img = list_tmp[0]  #cv2 format
        org_img_mutex.unlock()
        pix2 = pix.scaled(640, 480, QtCore.Qt.IgnoreAspectRatio, QtCore.Qt.SmoothTransformation)  #QtCore.Qt.KeepAspectRatio,
        self.pic_org.setPixmap(pix2)
        



if __name__ == '__main__':
    app = QApplication(sys.argv)
    myWin = MyWindow()
    myWin.show()
    sys.exit(app.exec_())



